package com.qingyun.edusysteam.config;

import cn.hutool.core.util.BooleanUtil;
import com.qingyun.edusysteam.dto.UserDTO;
import com.qingyun.edusysteam.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.qingyun.edusysteam.utils.RedisConstants.LOGIN_USER_KEY;
import static com.qingyun.edusysteam.utils.RedisConstants.LOGIN_USER_TTL;

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserHolder userHolder;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        String method = request.getMethod();

//        log.info("=== 拦截器处理请求 ===");
//        log.info("请求路径: {}", requestURI);
//        log.info("请求方法: {}", method);

        // 如果是OPTIONS预检请求，直接放行
        if ("OPTIONS".equals(method)) {
            log.info("OPTIONS预检请求，直接放行");
            return true;
        }

        // 获取Authorization请求头
        String token = request.getHeader("Authorization");
        if (token == null) {
            token = request.getHeader("authorization");
        }

//        log.info("获取到的token: {}", token);

        if (token == null || token.trim().isEmpty()) {
            log.info("Token为空，拦截请求: {}", requestURI);
            response.setStatus(401);
            return false;
        }

        String redisKey = LOGIN_USER_KEY + token;  // 根据 token 构造 redis key
//        log.info("Redis key: {}", redisKey);

        // 校验token是否有效
        try {
            Boolean hasKey = stringRedisTemplate.hasKey(redisKey);
//            log.info("Redis中是否存在key: {}", hasKey);

            if (BooleanUtil.isFalse(hasKey)) {
//                log.info("Token无效，拦截请求: {}", requestURI);
                response.setStatus(401);
                return false;
            }
             Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(redisKey);
             if(userMap != null && !userMap.isEmpty()){
                 UserDTO userDTO = cn.hutool.core.bean.BeanUtil.toBean(userMap, com.qingyun.edusysteam.dto.UserDTO.class);
                 userHolder.set(userDTO);
             }
        } catch (Exception e) {
//            log.error("Redis查询失败: {}", e.getMessage());
            response.setStatus(500);
            return false;
        }

//        log.info("Token有效，放行请求: {}", requestURI);
        Boolean expireIsSuccess = stringRedisTemplate.expire(redisKey, LOGIN_USER_TTL, TimeUnit.MINUTES);
        if (BooleanUtil.isTrue(expireIsSuccess)) {
            log.info("同时token有效期更新");
        }

        return true;
    }


    /**
     * Controller执行后、视图渲染前调用（可选，如修改响应数据）
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 可记录请求处理耗时、修改ModelAndView等
    }

    /**
     * 整个请求结束后调用（可选，如资源清理）
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理ThreadLocal中的用户信息，避免线程复用导致脏数据
        try {
            userHolder.clear();
        } catch (Exception ignore) {}
    }
}
